/**
 * 配置
 * */
package org.zmhhxl.user.configure;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.zmhhxl.common.core.constants.SecurityConstants;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Configuration(proxyBeanMethods = false)
public class JwtConfig {
    public static final String SECRET = "zmhhxl";
    public static final long EXPIRATION_TIME = 864_000_000; // 10天
    public static final String TOKEN_PREFIX = "Bearer ";
    public static final String HEADER_STRING = "Authorization";


   /**
    * zmhhxl 配合使用OAuth2TokenCustomizer
    * 自定义token部分就完成了，那么接下来就到resource server部分，早在最开始就添加了resource server的配置，
    * 将认证服务器也当做一个资源服务器，所以接下就在资源服务器文档中找到关于
    * 自定义jwt解析器，设置解析出来的权限信息的前缀与在jwt中的key
    *
    * 使用配置文件管理值以提高灵活性。
    *
    * @return jwt解析器 JwtAuthenticationConverter
    */
   /**
    *  在非流式配置中（MVC中），如果在流式reactive中，见gateway-resource
    *
    *  自定义jwt解析器，设置解析出来的权限信息的前缀与在jwt中的key
    *  @return jwt解析器 JwtAuthenticationConverter
    *
    * */
    @Bean
    public JwtAuthenticationConverter jwtAuthenticationConverter() {
       JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
       // 设置解析权限信息的前缀，设置为空是去掉前缀
       // 使用配置属性代替硬编码值
       grantedAuthoritiesConverter.setAuthorityPrefix(""); // 假设您已在配置文件中设置了该值
       // 设置权限信息在jwt claims中的key  // 使用配置文件可提高灵活性
       grantedAuthoritiesConverter.setAuthoritiesClaimName(SecurityConstants.AUTHORITIES_KEY); // 默认为"scope" 权限在token中的key

       JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
       converter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
       //使用此标记符来指定解析jwt的principalClaimName，默认是JwtClaimNames.SUB
       //jwtAuthenticationConverter.setPrincipalClaimName(JwtClaimNames.SUB);  //缺省是JwtClaimNames.SUB  AUD

       // 添加异常处理逻辑（示例）
//        try {
//            // 假设这里是对JWT解析器的额外配置，可能抛出异常
//            // 高级配置或外部服务调用
//        } catch (Exception e) {
       // 可以在此处添加备用方案或通知管理员等操作
//            // 记录日志或执行其他异常处理策略
//            // log.error("Error configuring JWT authentication converter", e);
//        }
       // todo 转换后没有授权权限内容???? 此bean在启动时被加载一次
       log.info("jwtAuthenticationConverter1 ===========");

       return converter;
    }

    /**
     * 自定义转换器
     * 可以new一个
     * */
   public static class CustomJwtGrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> {
      @Override
      public Collection<GrantedAuthority> convert(Jwt jwt) {
         List<String> roles = jwt.getClaimAsStringList("roles");
         if (roles == null) {
            roles = new ArrayList<>();
         }
         return roles.stream()
               .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
               .collect(Collectors.toList());
      }
   }

//   @Bean
//   public JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter() {
//      return new JwtGrantedAuthoritiesConverter() {
//         @Override
//         public Collection<? extends GrantedAuthority> convert(Map<String, Object> claims) {
//            Collection<? extends GrantedAuthority> authorities = super.convert(claims);
//            // 添加自定义逻辑生成权限
//            List<String> customAuthorities = (List<String>) claims.get("authorities");
//            if (customAuthorities != null) {
//               authorities.addAll(customAuthorities.stream()
//                     .map(SimpleGrantedAuthority::new)
//                     .collect(Collectors.toList()));
//            }
//            return authorities;
//         }
//      };
//   }

}
